package com.ale.oxetool.service;

import com.ale.oxetool.util.SSHUtil;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.TimeUnit;

/**
 * Created by guoshunw on 2016/5/19.
 */
public class SSHOXEConnection extends OXEConnection implements RemoteCommandService {

    private JSch jSch = new JSch();
    private Session sshSession;
    private static Logger log = LoggerFactory.getLogger(SSHOXEConnection.class);

    private static String resultEncoding = "UTF-8";

    public SSHOXEConnection(String host, String username, String password) throws IOException {
        super(host, username, password);
        //No OXE Settings, use default port
        setPort(22);
        init();
    }

    SSHOXEConnection(OXEServerSettings oxeServerSettings) throws IOException {
        super(oxeServerSettings);
        init();
    }

    @Override
    public boolean isSSHConnection() {
        return true;
    }

    private void init() throws IOException {
        this.connect(true);
    }

    @Override
    public boolean login(String username, String password) {
        return true;
    }


    @Override
    /**
     * This implementation has been tested more reliable. And it's
     * speed is faster aver < 30ms
     *
     * @param command
     *      command to be executed
     * */
    public String sendCommand(String command) throws IOException {
        try {
            return SSHUtil.execCommandByShell(this.sshSession, command, resultEncoding);
        } catch (JSchException e) {
            log.error("Execute remote command {} on host {} error", command, this.getHost());
            e.printStackTrace();
            return "";
        }
    }

    @Override
    public boolean connect(boolean autoLogin) throws IOException {
        try {
            sshSession = jSch.getSession(getUsername(), getHost(), getPort());
            // Never ask to enter "yes" on the first time.
            sshSession.setConfig("StrictHostKeyChecking", "no");
            sshSession.setPassword(this.getPassword().getBytes());
            sshSession.setTimeout((int) TimeUnit.MINUTES.toMillis(30));
            sshSession.connect();
        } catch (JSchException e) {
            e.printStackTrace();
            throw new IOException(e.getMessage());
        }
        return true;
    }

    @Override
    public void disconnect() {
        sshSession.disconnect();
    }

    @Override
    public boolean isConnected() {
        return sshSession.isConnected();
    }

}
